package cn.hinglo.common.interceptors.security;

import cn.hinglo.common.annotation.IgnoreToken;
import cn.hinglo.common.config.error.SelfErrorRender;
import cn.hinglo.common.constant.SystemConstant;
import cn.hinglo.common.enums.ResponseEnum;
import cn.hinglo.common.interceptors.base.BaseInterceptor;
import cn.hinglo.common.util.JwtKit;
import com.jfinal.aop.Invocation;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.annotation.Annotation;
import java.util.HashMap;
import java.util.Map;

/**
 * @createTime: 2018/2/11
 * @author: HingLo
 * @description: 登录认证拦截器
 */
@Slf4j
public class LoginInterceptor extends BaseInterceptor {
    /**
     * 排除拥有的指定的注解的方法
     *
     * @return 是否忽略
     */
    @Override
    public Class<? extends Annotation> ignoreAnnotation() {
        return IgnoreToken.class;
    }

    @Override
    public void preHandle(HttpServletRequest request, HttpServletResponse response, Invocation inv) {
        String authHeader = request.getHeader(SystemConstant.AUTHORIZATION);
        if (authHeader == null || !authHeader.startsWith(SystemConstant.REQUEST_PREFIX)) {
            // 如果请求头错误就直接返回了
            SelfErrorRender.errorRender(ResponseEnum.HEADERERROR, inv.getController());
        } else {
            // 取得token
            String token = authHeader.substring(SystemConstant.REQUEST_PREFIX.length());
            // 检测token是否有效
            Claims claims = JwtKit.parseJwt(token);
            if (claims == null) {
                SelfErrorRender.errorRender(ResponseEnum.TOKENINVALID, inv.getController());
                return;
            }
            // ======================== 将token与userId 用户信息传入到业务层中======================
            Map<String, Object> msg = new HashMap<>(3);
            msg.put(SystemConstant.PERMISSION_USER_ID, claims.getId());
            msg.put(SystemConstant.PERMISSION_TOKEN, token);
            msg.put(SystemConstant.PERMISSION_USER_BODY, claims.getSubject());
            msg.forEach(request::setAttribute);
            // ======================== 更新token======================
            if (claims.getExpiration().getTime() - System.currentTimeMillis() < SystemConstant.TOKEN_REFRESH) {
                response.setHeader(SystemConstant.AUTHORIZATION, JwtKit.createJwt(claims.getId(), claims.getSubject()));
            } else {
                response.setHeader(SystemConstant.AUTHORIZATION, token);
            }
            inv.invoke();
        }
    }


}
